package com.faner.fast.common.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.faner.fast.constant.CacheConstants;
import com.faner.fast.constant.CommonConstants;
import com.faner.fast.constant.enums.CodeEnum;
import com.faner.fast.constant.enums.DictTypeEnum;
import com.faner.fast.csv.utils.CsvUtils;
import com.faner.fast.email.pojo.vo.EmailDTO;
import com.faner.fast.email.service.EmailConfigService;
import com.faner.fast.excel.annotation.ResponseExcel;
import com.faner.fast.excel.context.ExcelListenerContext;
import com.faner.fast.excel.helper.EasyExcelHelper;
import com.faner.fast.file.FileProperties;
import com.faner.fast.upms.domain.bo.FileBO;
import com.faner.fast.upms.model.FileDO;
import com.faner.fast.upms.model.SysUserDO;
import com.faner.fast.upms.service.FileService;
import com.faner.fast.util.*;
import com.faner.fast.word.WordUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * description: CommonController
 * date: 2020/11/23 18:03
 * author: faner
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@Api(value = "common", tags = "公共模块")
public class CommonController {

    private final EmailConfigService emailConfigService;
    private final FileService fileService;
    private final ExcelListenerContext context;
    private final FileProperties fileProperties;
    private final RedisUtil redisUtil;

    @ApiOperation("下拉框参数")
    @RequestMapping(value = "/common/info",method= {RequestMethod.GET})
    public R<Map<Object, Object>> initSelectParams(){
        Map<Object, Object> result = new HashMap<>();
        Map<Object, String> codeMap = EnumUtils.convert2Map(CodeEnum.class, "code", "message");
        Map<Object, String> dictTypeMap = EnumUtils.convert2Map(DictTypeEnum.class, "type", "description");
        result.put("codeMap", codeMap);
        result.put("dictTypeMap", dictTypeMap);
        return  R.ok(result);
    }

    /**
     * 文件上传
     *
     * @param multipartHttpServletRequest 携带文件的 request
     * @return 文件信息
     */
    @ApiOperation("文件上传")
    @RequestMapping(value = "/common/file/upload",method= {RequestMethod.POST})
    public List<FileBO> upload(MultipartHttpServletRequest multipartHttpServletRequest) {
        MultiValueMap<String, MultipartFile> fileMap =
                multipartHttpServletRequest.getMultiFileMap();
        return fileService.upload(fileMap);
    }

    @ApiOperation("本地指定文件上传")
    @RequestMapping(value = "/common/file/local/upload",method= {RequestMethod.POST})
    public List<FileBO> localUpload(){
        MultiValueMap<String, MultipartFile> o1 = new LinkedMultiValueMap<String, MultipartFile>();
        String name ="C:\\Users\\范国洁\\Desktop\\微信图片_20201008134848.jpg";
        //上传oss
        MultipartFile file = new MockMultipartFile(name,name, MediaType.MULTIPART_FORM_DATA_VALUE, FileUtil.getByte(new File(name)));
        o1.add("file",file);
        return fileService.upload(o1);
    }


    @ApiOperation("文件下载")
    @PostMapping(value = "/common/file/down")
    public R downFile(@RequestParam String filePath,HttpServletRequest request, HttpServletResponse response){
//      String remoteFilePath = "http://hawk-att.oss-cn-beijing.aliyuncs.com/clinic/images/2020/11/25/16062972200406465.jpg";
        FileUtil.downloadFile(request,response,new File(filePath),false);
        return  R.ok();
    }


    @ApiOperation("发送邮件")
    @RequestMapping(value = "/common/email/send",method= {RequestMethod.POST})
    public R sendEamil(@Validated EmailDTO emailVO){
        emailConfigService.send(emailVO,emailConfigService.find());
        return  R.ok();
    }

    @ApiOperation("word导出")
    @GetMapping(value = "/common/word/export")
    public void wordExport(HttpServletResponse response){
        Map<String, Object> map = new HashMap<>();
        map.put("${title}", "title");
        map.put("${decption}", "decption");
        map.put("${author}", "author");
        Integer dayOfYear = LocalDateTime.now().getDayOfYear();
        map.put("${updateTime}", dayOfYear.toString());
        map.put("${content}", "content");
        WordUtil.export(map, response);
    }


    @SneakyThrows
    @ApiOperation("excel导出")
    @ResponseExcel(name = "fast", sheet = {"demoList","demoList2"},exclude = {"id","createTime","updateTime","delFlag"})
    @GetMapping("/common/excel/export")
    public List<List> excelExport() {
        //此处放到线程也可以
        ThreadLocalUtil.put("exclude",new String[]{"path"});

        List<List> objects = new ArrayList<>();
        List<FileDO> dataList = fileService.list();

        List<SysUserDO> dataList2 = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            SysUserDO sysUserDO = new SysUserDO();
            sysUserDO.setNickName("tr1-" + i);
            dataList2.add(sysUserDO);
        }

        objects.add(dataList);
        objects.add(dataList2);
        return objects;
    }

    @SneakyThrows
    @ApiOperation("excel读取")
    @GetMapping("/common/excel/read")
    public void excelRead(@RequestParam String filePath,HttpServletResponse response) {
        EasyExcelHelper.read(fileProperties.getStoreDir()+"/"+filePath,context.getEventListener("FileEventListener", response));
        EasyExcelHelper.read(com.faner.fast.file.FileUtil.getFileAbsolutePath(fileProperties.getStoreDir(),filePath),context.getEventListener("FileEventListener", response));
    }

    @ApiOperation("csv导出")
    @GetMapping("/common/csv/export")
    public void csvExport() {
        List<FileDO> list = new ArrayList<>();
        FileDO fileDO = new FileDO();
        fileDO.setName("faner");
        list.add(fileDO);
        CsvUtils.getInstance().exportObjects2CSV(list, FileDO.class, "J.csv");
    }

    @ApiOperation("csv读取")
    @GetMapping("/common/csv/import")
    public void csvImport() {
        List<FileDO> list = CsvUtils.getInstance().readCSV2Objects("D:\\java-project\\fast\\J.csv", FileDO.class);
        for (FileDO demoData : list) {
            System.out.println(demoData);
        }
    }

    @SneakyThrows
    @ApiOperation("生成验证码")
    @GetMapping(value = "/common/verification")
    public R generateVerificationCode(HttpServletRequest request){
        // 自定义纯数字的验证码（随机4位数字，可重复）
        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 45, 4, 10);
        captcha.setGenerator(randomGenerator);
        captcha.setFont(new Font("黑体",Font.BOLD,36));
        captcha.setBackground(new Color(228,221,221));
        captcha.createCode();
        String generate = randomGenerator.generate();
        log.info("生成验证码 ：{}",generate);
        Image image = captcha.createImage(generate);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write((RenderedImage) image, "jpg", outputStream);
        BASE64Encoder encoder = new BASE64Encoder();
        String imageStr=encoder.encode(outputStream.toByteArray());
        request.getSession().setAttribute(CommonConstants.SESSION_KEY, generate);
        // <img src="data:image/png;base64,此处填base64编码"/>
        return R.ok(imageStr);
    }

    @Autowired
    private CaptchaService captchaService;

    @RequestMapping("/common/captcha")
    public R captcha(){
        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setCaptchaType("blockPuzzle");
        ResponseModel responseModel = captchaService.get(captchaVO);
        Object repData = responseModel.getRepData();
        final CaptchaVO captchaVO1 = JSONUtil.parseObj(repData).toBean(CaptchaVO.class);
        String token = captchaVO1.getToken();
        System.out.println("token:" + token);
        return R.ok(captchaVO1);
    }


    public static void main(String[] args) {
        System.out.println(DateUtil.offsetHour(new Date(), 24));
    }

    @ApiOperation("redis")
    @RequestMapping("/common/redis")
    public R redis(){
        final HashMap<Object, Object> map = new HashMap<>();
        map.put("a","1");
        map.put("b","2");
        redisUtil.hset(CacheConstants.USER_DETAILS,"fan", map);
        redisUtil.hset("fan","1",map);
        final Map<Object, Object> fan = redisUtil.hmget("fan");
        return R.ok(fan);
    }

}
